/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
<template>
    <div class="model-training__wrap">
        <flow-common-top
            :total-flag="true"
            @roll-back="refreshAIFlow"
            @version-total="getVersionTotal" />
        <empty-panel v-if="nullDataSource"
                     :text="emptyText" />
        <div v-else
             class="submit-training__container">
            <div class="submit-training__step">
                <sf-step
                    v-model="stepNum"
                    class="python-step_panel"
                    :use-in-modal="true"
                    align-center>
                    <sf-step-item
                        v-for="(item, index) in stepTitleList"
                        :key="index"
                        :title="item"
                        @click.native="_handleClickStep(index)" />
                </sf-step>
                <sf-tab-panel
                    ref="optionsTabpanel"
                    size="large"
                    :title-hide="true">
                    <sf-tab-item>
                        <set-training-data
                            ref="trainingForm"
                            :second-right-data="tagData"
                            :right-data="trainingData"
                            :left-data="trainingLeftData"
                            :init-data="trainAllData" />
                    </sf-tab-item>
                    <sf-tab-item v-if="showAlgorithmType">
                        <set-algorithm-type
                            ref="algorithmType"
                            @select-algorithm-type="chooseAlgorithmType" />
                    </sf-tab-item>
                    <sf-tab-item>
                        <set-algorithm-form
                            ref="setAlgorithm"
                            :time-field-list="timeFieldList" />
                    </sf-tab-item>
                    <sf-tab-item>
                        <resource-config-form
                            ref="resourceConfig"
                            class="justify-center"
                            :submit-data="resourceData"
                            :default-width="480"
                            :label-name="_('资源管理')" />
                    </sf-tab-item>
                    <sf-tab-item>
                        <set-finish
                            ref="setFinish"
                            :training-obj="getTrainData"
                            :algorithm-obj="getAlgorithmData"
                            :resource-obj="getResourceData" />
                    </sf-tab-item>
                </sf-tab-panel>
            </div>
        </div>
        <div v-if="!nullDataSource"
             class="training-drawer__footer">
            <sf-button
                v-show="stepNum > 0"
                :class="{ 'first-btn': stepNum > 0 }"
                @click="back()">
                上一步
            </sf-button>
            <sf-button-primary
                v-show="stepNum !== stepTitleList.length - 1"
                :class="{ 'step-btn': stepNum === 0 }"
                @click="next()">
                下一步
            </sf-button-primary>
            <sf-button-primary v-show="stepNum === stepTitleList.length - 1"
                               @click="_saveSubmit">
                <lang>生成训练任务</lang>
            </sf-button-primary>
            <!-- <sf-button v-show="stepNum !== stepTitleList.length - 1"
                       @click="_cancelSubmit">
                清 空
            </sf-button> -->
        </div>
    </div>
</template>
<script>

import { deepClone } from 'src/util/deep_clone';
import setAlgorithmType from './component/set_algorithm_type';
import setAlgorithmForm from './component/set_algorithm_form';
import setFinish from './component/set_finish';
import setTrainingData from './component/select_training_data';

import resourceConfigForm from 'src/home/mod_cluster/common/common_form/resource_config_form';
import trainingUrlAdapter from 'src/home/mod_common/training_url_adapter';

import selectDataTransfrom from 'src/util/select_transform.ts';
import EmptyPanel from 'src/components/empty_panel.vue';
import parseJson from 'src/util/parse_json.ts';

const DEFAULT_FORMDATA = {
    trainObj: {
        trainColumns: [],
        labelColumns: ['']
    }
};
import FlowCommonTop from '../components/flow_common_top.vue';

import FlowOpr from '../components/common/flow_opr.js';



const FLOW_URL = {
    post: trainingUrlAdapter('flow'),
    put: trainingUrlAdapter('flow'),
    get: trainingUrlAdapter('flow')
};

export default {
    components: {
        setAlgorithmForm,
        setFinish,
        setTrainingData,
        resourceConfigForm,
        FlowCommonTop,
        EmptyPanel,
        setAlgorithmType
    },
    mixins: [FlowOpr],
    computed: {
        showAlgorithmType () {
            return !!this.aiFlowType;
        },
        stepTitleList () {
            if (!this.showAlgorithmType) {
                return [_('选择数据'), _('算法模板配置'), _('训练资源配置'), _('完成')];
            }
            return [_('选择数据'), _('选择算法模式'), _('算法模板配置'), _('训练资源配置'), _('完成')];
        },
        aiFlowType () {
            return +this.$route.query.aiFlowType || 0;
        },
        projectId () {
            return this.$route.query.projectId || '';
        },
        aiFlowId () {
            return this.$route.query.aiFlowId || '';
        },
        flowName () {
            return this.$route.query.flow_name || '';
        }
    },

    data () {
        return {
            stepNum: 0, // 当前步骤，从0开始，0为第一步
            algorithmList: [], //算法列表
            timeFieldList: [], //时间字段列表
            trainAllData: [], //选择的所有字段数据
            trainingData: [], //训练数据
            trainingLeftData: [], //初始化左边数据
            tagData: [], //标签数据
            formData: { ...DEFAULT_FORMDATA },
            getTrainData: {
            },
            getAlgorithmData: {
            },
            getResourceData: {
            },
            getAlgorithmTypeData:{

            },
            submitParams: {},
            isPushSuccess: false,
            trainingId: '',
            ruleGraphList: [],
            nullDataSource: false,
            emptyText: _('您还未导入数据源，请先到【数据加载】节点导入数据集。'),
            taskParams: {},
            trainingVersion: '',
            resourceData: {},
            nullAIInfo: false,
            taskSuccessFlag: false

            // globalParams: { ...DEFAULT_GLOBAL_PARAMS }
        };
    },

    beforeRouteLeave (to, from, next) {
        if (this.nullAIInfo || this.taskSuccessFlag) {
            this.saveAiFlowInfo({});
            next(true);
            return;
        }
        this.cacheAIFlowInfo();
        if (to.name === 'data_load' || to.name === 'feature_manager') {
            next(true);
            return;
        };
        this.$confirm({
            title: _('提示'),
            msg: _('AI FLOW 尚未保存，是否离开当前页面？'),
            autoDestroy: true,
            autoClose: true,
            buttons: [{
                cls: 'visual-save-exit-btn',
                actionName: 'leave',
                loading: true,
                text:  _('直接离开')
            }, {
                actionName: 'submit',
                loading: true,
                text:_('保存并离开')
            }, {
                actionName: 'cancel',
                text: '取消'
            }],
            leave: () => {
                this.saveAiFlowInfo({});
                next(true);
            },
            submit: () => {
                this._saveGraph().then(() => {
                    this.saveAiFlowInfo({});
                    next(true);
                });
            }
        });
    },
    mounted () {
        if (this.isNullObject(this.aiFlowInfo)) {
            this._getAIFlowSnapShot();
        } else {
            this.handleAIFlowInfo(this.aiFlowInfo);
        }
    },
    methods: {

      
        chooseAlgorithmType (type) {
            this.stepNum++;
            this._getIntoStep(this.stepNum);
            let setAlgorithm = this.$refs.setAlgorithm;

            //type如果是1，则为快速算法
            setAlgorithm && setAlgorithm.setJsonValue({isAutoMl:type, algorithmId:''});
            setAlgorithm._getAlogrithmList();
        },
        
        
        refreshAIFlow (data) {
            this.stepNum = 0;
            this._getIntoStep(0);
            this.handleAIFlowInfo(data);
        },
       
        handleAIFlowInfo (data) {
            let { graphInfo, trainingInfo } = data;
            if (!graphInfo.graphRule) {
                return;
            }
            this.saveAiFlowInfo(data);


            //全部list
            let lastColumns = parseJson(graphInfo.lastColumns);
            let trainAllData = lastColumns;
            this.trainAllData = selectDataTransfrom(trainAllData);

            //训练数据
            let trainingData = parseJson(trainingInfo.trainColumns);

            this.trainingData = selectDataTransfrom(trainingData);

            //标签数据
            let tagData = parseJson(trainingInfo.labelColumns);
            this.tagData = selectDataTransfrom(tagData);



            //左表单数据
            let trainingLeftData = this.getIncludes(trainAllData, trainingData, tagData);
            this.trainingLeftData = selectDataTransfrom(trainingLeftData);

            this.$refs.setAlgorithm.setJsonValue(trainingInfo);
            this.resourceData = {
                cpuNum: trainingInfo.cpuNum,
                memorySize: trainingInfo.memorySize,
                gpuNum: trainingInfo.gpuNum
            };


            let timeFieldList = parseJson(graphInfo.allColumns);
            this.timeFieldList = selectDataTransfrom(timeFieldList);

            if (this.showAlgorithmType) {
                this.$refs.algorithmType && this.$refs.algorithmType.setJsonValue(trainingInfo);
            }
        },

        //获取图规则
        async _getAIFlowSnapShot () {
            let getSnapShotURL = `${FLOW_URL.get}/${this.aiFlowId}`;
            this.$mask();
            let jsonData = await this.$ajax.get(getSnapShotURL, { aiFlowId: this.aiFlowId });
            this.$unmask();
            let { success, msg, data } = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            };
            if (!data.graphInfo) {
                this.nullDataSource = true;
                this.nullAIInfo = true;
                return false;
            }
            this.handleAIFlowInfo(data);

        },
        _handleClickStep (index) {

            //点当前步骤，不执行。
            if (this.stepNum === index) {
                return false;
            };
            this.getAlgorithmTypeData = this.$refs.algorithmType && this.$refs.algorithmType.getJsonValue();
            /*eslint-disable*/
            
            if (this.showAlgorithmType && index === 2 && this.getAlgorithmTypeData.isAutoMl < 0) {
                this.stepNum = 1;
                this._getIntoStep(1);
                this.$warn(_('请先选择选择算法模式'), { autoHide: true });
                return false;
            }
            this.stepNum = index;
            let setAlgorithm = this.$refs.setAlgorithm;
            this.getAlgorithmData = setAlgorithm && setAlgorithm.getJsonValue();
            this.getTrainData = this.$refs.trainingForm && this.$refs.trainingForm.getJsonValue();
            this.getResourceData = this.$refs.resourceConfig && this.$refs.resourceConfig.getJsonValue();
            this._getIntoStep(index);
        },
        validateAlgorithmData(){
            let setAlgorithm = this.$refs.setAlgorithm;
            if (!setAlgorithm.isValid()) {
                this.$showErr(setAlgorithm.getInvalidMsgs());
                return false;
            };
        
            let algorithmData = setAlgorithm.getJsonValue();
            this.getAlgorithmData = algorithmData;
        },
        // 切换步骤
        next () {
            /*eslint-disable*/
            if (this.stepNum === 0) {
                this.getTrainData = this.$refs.trainingForm && this.$refs.trainingForm.getJsonValue();
                if (!this.getTrainData.trainColumns.length) {
                    this.$warn(_('请先选择训练数据'), { autoHide: true });
                    return false;
                }
            };


            if (this.stepNum === 1) {
                if (this.showAlgorithmType) {
                    this.getAlgorithmTypeData = this.$refs.algorithmType && this.$refs.algorithmType.getJsonValue();
                    if (this.getAlgorithmTypeData.isAutoMl < 0) {
                        this.$warn(_('请先选择选择算法模式'), { autoHide: true });
                        return false;
                    }
                }else{
                    let setAlgorithm = this.$refs.setAlgorithm;
                    if (!setAlgorithm.isValid()) {
                        this.$showErr(setAlgorithm.getInvalidMsgs());
                        return false;
                    };
                
                    let algorithmData = setAlgorithm.getJsonValue();
                    this.getAlgorithmData = algorithmData;
                }
            }

            if (this.stepNum === 2) {
                if (this.showAlgorithmType) {
                    let setAlgorithm = this.$refs.setAlgorithm;
                    if (!setAlgorithm.isValid()) {
                        this.$showErr(setAlgorithm.getInvalidMsgs());
                        return false;
                    };
                
                    let algorithmData = setAlgorithm.getJsonValue();
                    this.getAlgorithmData = algorithmData;
                }else{
                     let resourceConfig = this.$refs.resourceConfig;
                    if (!resourceConfig.isValid()) {
                        this.$showErr(resourceConfig.getInvalidMsgs());
                        return false;
                    };
                    this.getResourceData = resourceConfig.getJsonValue();
                }
            }


            if (this.stepNum < this.stepTitleList.length) {
                this.stepNum++;
                this._getIntoStep(this.stepNum);
            }
        },

        back () {
            if (this.stepNum > 0) {
                this.stepNum--;
                this._getIntoStep(this.stepNum);
            }
        },

        //关闭弹窗
        _cancelSubmit () {
            if (this.stepNum === 0) {
                this.$refs.trainingForm && this.$refs.trainingForm.reset();
            } else if (this.stepNum === 1) {
                this.$refs.setAlgorithm && this.$refs.setAlgorithm.reset();
            } else {
                this.resourceData = {
                    cpuNum: 1,
                    memorySize: 1,
                    gpuNum: 0
                }
            }
        },

        _getIntoStep (stepNum) {
            this.$refs.optionsTabpanel && this.$refs.optionsTabpanel.setActiveItem(stepNum);
        },
        cacheAIFlowInfo () {
            let taskParams = deepClone(this.aiFlowInfo).trainingInfo;
            this.getAlgorithmData = this.$refs.setAlgorithm && this.$refs.setAlgorithm.getJsonValue();
            this.getTrainData = this.$refs.trainingForm && this.$refs.trainingForm.getJsonValue();
            this.getResourceData = this.$refs.resourceConfig && this.$refs.resourceConfig.getJsonValue();

            Object.assign(taskParams, this.getAlgorithmData, this.getResourceData);
            taskParams.trainColumns = JSON.stringify(this.getTrainData.trainColumns);
            taskParams.labelColumns = JSON.stringify(this.getTrainData.labelColumns);
            if (this.showAlgorithmType) {
                taskParams.isAutoMl = this.$refs.algorithmType && this.$refs.algorithmType.getJsonValue().isAutoMl;
            }
            this.aiFlowInfo.trainingInfo = taskParams;
            this.aiFlowInfo.algorithmId = taskParams.algorithmId;
            this.saveAiFlowInfo(this.aiFlowInfo);
        },

        async _saveSubmit () {
            this.getTrainData = this.$refs.trainingForm && this.$refs.trainingForm.getJsonValue();
            if (!this.getTrainData.trainColumns.length) {
                this.stepNum = 0;
                this._getIntoStep(0);
                return this.$warn(_('请先选择训练数据'), { autoHide: true });
            }
            let setAlgorithm = this.$refs.setAlgorithm;
            if (!setAlgorithm.isValid()) {
                let index = this.showAlgorithmType ? 2 : 1;
                this.stepNum = index;
                this._getIntoStep(index);
                return this.$showErr(setAlgorithm.getInvalidMsgs());
            };
            let resourceConfig = this.$refs.resourceConfig;
            if (!resourceConfig.isValid()) {
                let idx = this.showAlgorithmType ? 3 : 2;
                this.stepNum = idx;
                this._getIntoStep(idx);
                this.$showErr(resourceConfig.getInvalidMsgs());
                return false;
            };
            let version = this.versionFormat(this.trainingVersion);
            this._saveGraph(version);
        },
        async _saveGraph (version = null) {
            this.cacheAIFlowInfo();
            const SAVEURL = `${FLOW_URL.put}/${this.aiFlowId}/snapshot`;
            let params = deepClone(this.aiFlowInfo);
            params.version = version;
            params.trainingInfo.projectId = this.projectId;
            params.trainingInfo.flowName = this.flowName;
            params.trainingInfo.dataSourceId = params.dataSourceId;
            params.trainingInfo.tableName = params.graphInfo.dataSourceName;
            params.trainingInfo.aiFlowType = this.aiFlowType;
            //如果是小白算法
            if (params.trainingInfo.isAutoMl === 1) {
                let getAutoAlogorithmURL = trainingUrlAdapter('algorithm/autoAlgorithm');
                let getAutoAlogorithmData = await this.$ajax.get(getAutoAlogorithmURL);
                let autoAlogorithmData = getAutoAlogorithmData.data;
                params.trainingInfo.algorithmId = autoAlogorithmData.id;
                params.trainingInfo.algorithmName = 'autoML';
                params.trainingInfo.configJson = autoAlogorithmData.paramsDescription;
                params.algorithmId = autoAlogorithmData.id;
            }
          
            this.$mask();
        
            let jsonData = await this.$ajax.put(SAVEURL, params);
            let { success, msg, data } = jsonData;
            this.$unmask();
            if (!success) {
                return this.$showErr(msg || _('创建AI Flow版本失败'));
            };
            if (version) {
                this.taskSuccessFlag = true;
                let query = deepClone(this.$route.query);
                delete query.aiFlowId;
                this.$router.push({
                    path: `/project_manager/project_index/visual_task_manager`,
                    query: Object.assign(query, { periodic: this.getAlgorithmData.periodic })
                });
            }
        },
        getTrainingData (list) {
            if (!list.length) {
                return [];
            }
            let nameObj = list[0];
            let trainingArr = [];
            for (let key in nameObj) {
                trainingArr.push({ name: key });
            };
            for (let i = 0; i < trainingArr.length; i++) {
                let value = list.map(item => item[trainingArr[i].name]).slice(0, 3).join(',');
                trainingArr[i].value = value;
            }
            return trainingArr;
        },
        getIncludes (allArr, arrFirst, arrSecond) {
            let arr = arrFirst.concat(arrSecond);
            let includesArr = allArr.filter(items => {
                if (!arr.includes(items)) return items;
            })
            return includesArr;
        },
        versionFormat (version) {
            if (!version) {
                return 'V1'
            }
            let val = +version + 1;
            return `V${val}`;
        },
        getVersionTotal (total) {
            this.trainingVersion = total;
        }


    },
    destroyed () {
        this.isPushSuccess = false;
    }

};
</script>
<style lang="less">
.visual-save-exit-btn {
    margin-right: 66px;
}
.model-training__wrap {
    height: 100%;
    position: relative;
    .cluster-empty-panel__container {
        height: calc(100% - 160px);
    }
}
.training-drawer__footer {
    position: absolute;
    bottom: 18px;
    padding-top: 8px;
    width: 100%;
    text-align: center;
    .sfv-btn {
        margin-right: 8px;
    }
    .first-btn {
        margin-left: -470px;
    }
    .step-btn {
        margin-left: -532px;
    }
}
.submit-training__container {
    .justify-center {
        justify-content: center;
        margin-top: 15px;
    }
    .submit-training__step {
        width: 800px;
        margin: 24px auto 0;
    }

    position: relative;
    .sfv-steps__wrap-modal {
        margin-top: 0px;
    }
    .sfv-tabpanel {
        margin: 10px 32px 0;
    }
    .sfv-tabpanel_wrap {
        box-shadow: none;
        overflow-x: hidden;
        overflow-y: auto;
    }

    .sfv-tabpanel_header {
        display: none; // 不显示tabpenal的header
    }
}
</style>
